#! /usr/bin/env python
# process individual brain images. 

# INPUT: 
# 1. A list of brain images that is going to be processed (a directory of images plus a list)
# 2. What to do with the given list of brain images

# OUTPUT and EFFECT:
# -. processed images saved at the designated directory along with the transformation 
#    applied. 

# ===================================================================================
# DESIGN CONSIDERATIONS:
# Input can be from command-line arguments and/or a configuration file.
# Currently, implement the configuration file approach for simplility
# ===================================================================================

# use __future__ to run in Python 2.5.X 
from __future__ import with_statement
import sys  
import os
import ConfigParser
import logging
import subprocess
#sys.path.append("~/projects/FXTAS/tools")

###### parameter parsing #####
if len(sys.argv) < 2:
	print 'usage'
	print '-----'
	print ''
	print 'individual config_file'
	print ' '
	print 'Inputs:'
	print '-------'
	print 'The configuration file that discribes the jobs and the dispatching setup.'
	print 'For more information please refer to the in-line comments in the example.conf.'
	sys.exit(1)

###### read in configuration file ##### 
config=ConfigParser.SafeConfigParser(defaults=dict({"working_directory":'.', "engine":'/home/xqwang/projects/FXTAS/tools/bin/actions.py'}))
config_file = os.path.abspath(os.path.expanduser(sys.argv[1]))
if os.path.exists(config_file):
    config.read(config_file)
else:
    print 'config_file does not exist'
    sys.exit(1)

engine = os.path.expanduser(config.get('individual', 'engine')) 
job_name = config.get('individual','job_name')
object_directory = os.path.expanduser(config.get('individual','object_directory'))
format = config.get('individual', 'format')
working_directory = os.path.expanduser(config.get('individual','working_directory'))
action_list = config.get('individual','actions').split(',')
action_list = map(lambda item: item.strip(), action_list) 
# parsing the action_list into a list of (action, directory) pairs
action_list=map(lambda item: item.split(':'), action_list) 

os.chdir(working_directory)
#if not os.path.isdir(job_name): 
#    os.mkdir(job_name)
#
#os.chdir(job_name)
 
###### preparing log facility #####
# TODO: use logging.config functionality so that all the setting can be read and changed
# in the configuration file

log_file = job_name+'.log' 
log_level = config.getint('individual', 'log_level')
logger = logging.getLogger(job_name)
fh = logging.FileHandler(log_file,"w")
fh.setLevel(log_level)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
fh.setFormatter(formatter)
logger.addHandler(fh)
if log_level <= logging.INFO:  # in debugging mode, displace logs to stdout
    ch = logging.StreamHandler()
    ch.setLevel(log_level)
    ch.setFormatter(formatter)
    logger.addHandler(ch)

logger.setLevel(log_level)
logger.debug("job: "+job_name+" started ...")

# Start actions

image_list = config.get('individual','images')
if os.path.isdir(os.path.expanduser(image_list)):
    import glob
    image_list=glob.glob1(os.path.expanduser(image_list),"*"+format)
    image_list=map(lambda image: image.split('.')[0], image_list)
elif os.path.isfile(os.path.expanduser(image_list)):
    image_list=file(os.path.expanduser(image_list)).readlines()
else:
    image_list=image_list.split(',')
image_list=map(lambda image: image.strip(), image_list)
logger.debug("Total %d images are to be processed", len(image_list))

for image in image_list:
    #image_name=object_directory+"/"+image+".hdr" 
    domain=object_directory
    dependency_id=""
    for (action,codomain) in action_list: 
        job_id= job_name+"_"+image
        codomain=os.path.abspath(os.path.expanduser(codomain))
        if not os.path.exists(codomain):
            os.mkdir(codomain)
        if dependency_id=="": 
	    logger.debug("submitting jobs: %s", job_id) 
            #subprocess.check_call(["qsub","-cwd", "-N", job_id, "-S", "/opt/sage-4.7.1/bin/sage", "-v", "SAGE_PATH", engine, action, image+format, domain, codomain]) 
            #subprocess.check_call(["qsub","-cwd", "-N", job_id, "-S", "/usr/bin/python", "-v", "PYTHONPATH", engine, action, brain, domain, codomain]) 
            subprocess.check_call(["qsub","-cwd", "-N", job_id, "-b", "yes", engine, action, image+format, domain, codomain]) 
            dependency_id=job_id
            #try:
            #    subprocess.check_call([engine, action, brain, domain, codomain]) 
            #except subprocess.CalledProcessError as err:
            #    logger.error(err)    
	    #    logger.info(brain+" was not processed.")
            #    pass
            #domain=codomain
        else:
            #subprocess.check_call(["qsub","-cwd", "-N", job_id, "-S", "/opt/sage-4.7.1/bin/sage", "-v", "SAGE_PATH", "-hold_jid", dependency_id, engine, action, image+format, domain, codomain]) 
            subprocess.check_call(["qsub","-cwd", "-N", job_id, "-b", "yes", "-hold_jid", dependency_id, engine, action, image+format, domain, codomain]) 
            dependency_id=job_id
            domain=codomain
